#ifndef SEGMENTTREE_H
#define SEGMENTTREE_H

/**
 * \file	segmenttree.h
 * \brief	Declaration de la classe SegmentTree representant un arbre hierarchique de segments.
 */

#include "segmentlist.h"
#include "boundingbox.h"

/*! \def OWN_COLOR
  display mode : displays the segment of the node with its own color;
 */
#define OWN_COLOR 0

/*! \def OTHER_COLOR
  display mode : displays the segment of the node with a color specified by the user.
 */
#define OTHER_COLOR 1

/*! \def MESH_COLOR
  display mode : displays the segment of the node the color of the points on the mesh.
 */
#define MESH_COLOR 2

/*! \def PICKING
  display mode : the render mode has to be activate before using this display mode. Only used for picking solutions.
 */
#define PICKING 3

class SegmentTree
{
	/*!
	 * \class SegmentTree
	 * \brief Classe représentant un arbre hierarchique de segments (donnes a partir d'une map) sur un maillage par un critere d'inclusion.
	 * 
	 * Classe représentant la hierarchie des segments d'une surface par critere d'inclusion :
	 * Chaque SegmentTree est un noeud d'un arbre dont les fils sont tous les segments inclus dans le segment du noeud.
	 * On accede aux fils comme suit :
	 * - Un acces direct au premier fils.
	 * - Puis des acces au fils suivant par parcours des freres successifs du premier fils.
	 *
	 * \todo Il faudra penser a changer l'operateur d'affectation de la classe SegmentTree et, chager en consequence les passages en parametre par reference dans les methodes de calcul des links. Meme si ca fait gagner du temps comme ca, en changeant ca fera surement plus propre. !!! L'OPERATEUR D'AFFECTATION A ETE REPARE !!!
	 *
	 */
	private :
		Segment*		segment;			/*! Segment represented by the node.*/
		SegmentTree*	son;				/*! Pointer to the node's  direct son.*/
		SegmentTree*	brother;			/*! Pointer to the node's direct brother.*/
		
		Vector3D		color;				/*! Color of the node. */
		string			name;				/*! Name of the node. Empty in most of the case, used only for automatic labelling from a template. */
		
	public:
		/*!
		*  \brief Default constructor of the SegmentTree class.
		*
		*  Default constructor of the SegmentTree class : Every attributes are initialized to 0 (int,float,double,...) NULL (pointers) or are cleared (lists, stacks, ...).
		*/
		SegmentTree();
		
		/*!
		*  \brief Copy constructor of the SegmentTree class.
		*
		*  Copy constructor of the SegmentTree class.
		*/
		SegmentTree( const SegmentTree& _tree );
		
		/*!
		*  \brief Destructor of the SegmentTree class.
		*
		*  Destructor of the SegmentTree class.
		*  Destoy the node, all its brothers, and all its sons.
		*/
		~SegmentTree();
		
		/*!
		*  \brief Affectation operator of the SegmentTree class.
		*
		*  Affectation operator of the SegmentTree class.
		*/
		SegmentTree& operator= ( const SegmentTree& _tree );
		
		/*!
		*  \brief Getter of the SegmentTree class.
		*
		*  Getter of the SegmentTree class.
		*
		*  \return (Segment) Returns the Segment represented in the node.
		*/
		Segment* getSegment ();
		
		/*!
		*  \brief Getter of the SegmentTree class.
		*
		*  Getter of the SegmentTree class.
		*
		*  \return (SegmentTree) Returns a pointer to the node's son.
		*/
		SegmentTree* getSon ();
		
		/*!
		*  \brief Getter of the SegmentTree class.
		*
		*  Getter of the SegmentTree class.
		*
		*  \return (SegmentTree) Returns a pointer to the node's brother.
		*/
		SegmentTree* getBrother ();
		
		/*!
		*  \brief Getter of the SegmentTree class.
		*
		*  Getter of the SegmentTree class.
		*
		*  \return (Vector3D) Returns the color of the node.
		*/
		Vector3D getColor ();
		
		/*!
		*  \brief Getter of the SegmentTree class.
		*
		*  Getter of the SegmentTree class.
		*
		*  \return (string) Returns the name of the node.
		*/
		string getName ();
		
		/*!
		*  \brief Getter of the SegmentTree class.
		*
		*  Getter of the SegmentTree class.
		*
		*  \return (double*) Returns the color of the node as an array of double.
		*/
		double* getColorArray ();
		
		/*!
		*  \brief Method to get the number of sons of a node.
		*
		*  Method to get the number of sons of a node.
		*
		*  \return (int) Returns the number of sons of the node.
		*/
		int getNbSons ();
		
		/*!
		*  \brief Method to get the number of brothers of a node.
		*
		*  Method to get the number of brothers of a node.
		*
		*  \return (int) Returns the number of brothers of the node.
		*/
		int getNbBrothers ();
		
		/*!
		*  \brief Method to get the maximum depth of the node's leaves.
		*
		*  Method to get the maximum depth of the node's leaves.
		*
		*  \return (double) Returns the maximum depth of the node's leaves.
		*/
		double getMaxDepth ();
		
		/*!
		*  \brief Method to get the minimum depth of the node's leaves.
		*
		*  Method to get the minimum depth of the node's leaves.
		*
		*  \return (double) Returns the minimum depth of the node's leaves.
		*/
		double getMinDepth ();
		
		/*!
		*  \brief Setter of the SegmentTree class.
		*Setter
		*  Getter of the SegmentTree class.
		*
		*  \param _s : Segment to attribute to the node.
		*
		*  \return (void)
		*/
		void setSegment ( Segment* _s );
		
		/*!
		*  \brief Setter of the SegmentTree class.
		*
		*  Setter of the SegmentTree class.
		*
		*  \param _son : Son to attribute to the node.
		*
		*  \return (void)
		*/
		void setSon ( SegmentTree* _son );
		
		/*!
		*  \brief Setter of the SegmentTree class.
		*
		*  Setter of the SegmentTree class.
		*
		*  \param _brother : Brother to attribute to the node.
		*
		*  \return (void)
		*/
		void setBrother ( SegmentTree* _brother );
		
		/*!
		*  \brief Setter of the SegmentTree class.
		*
		*  Setter of the SegmentTree class.
		*
		*  \param _color : Color to attribute to the node.
		*
		*  \return (void)
		*/
		void setColor ( Vector3D _color );
		
		/*!
		*  \brief Setter of the SegmentTree class.
		*
		*  Setter of the SegmentTree class.
		*
		*  \param _name : Name to attribute to the node.
		*
		*  \return (void)
		*/
		void setName ( string _name );
		
		/*!
		*  \brief Adds a son to the node.
		*
		*  Adds a son to the node.
		*
		*  \param _st : Segment tree to add as a son of the node.
		*
		*  \return (void)
		*/
		void addSon ( SegmentTree* _st );

		/*!
		*  \brief Adds a brother to the node.
		*
		*  Adds a brother to the node.
		*
		*  \param _st : Segment tree to add as a brother of the node.
		*
		*  \return (void)
		*/
		void addBrother ( SegmentTree* _st );
		
		/*!
		*  \brief Clears a node, its sons and brothers.
		*  
		*  Clears a node, its sons and brothers.
		*
		*  \return (void)
		*/
		void clear ();
		
		/*!
		*  \brief !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
		*  
		*  ##########################################################
		*
		*  \return (void)
		*/
		void copy ( SegmentTree* _tree );
		
		/*!
		*  \brief Indicates wether the segments intersect or not.
		*  
		*  Indicates wether the segments intersect or not.
		*
		*  \param _s : Segment we want to know if it intersects with the calling segment.
		*
		*  \return (bool) Returns true if the segments intersect, false else.
		*/
		bool intersects ( SegmentTree* _s );
		
		/*!
		*  \brief Indicates wether the segments intersect or not and how big is the intersection.
		*  
		*  Indicates wether the segments intersect or not and how big is the intersection.
		*
		*  \param _s : Segment we want to know if it intersects with the calling segment.
		*
		*  \return (int) Returns the number of vertices compining th segments intersection.
		*/
		int intersectsQuantity ( SegmentTree* _s );
		
		/*!
		*  \brief Merges two nodes.
		*  
		*  Merges two nodes :
		*  The calling node will be added all the parameter node's vertices and sons. It's a kind of addition.
		*
		*  \param _s : Segment we want to merge with the calling segment.
		*
		*  \return (void)
		*/
		void merge ( SegmentTree* _s );
		
		/*!
		*  \brief Recursive method which creates a tree node from a segment picked into a list of all segment presents on the mesh.
		*
		*  Recursive method which creates a tree node from a segment picked into a list of all segment presents on the mesh :
		*  Creates the node from the segment AND the sons hierarchy of the node.
		*
		*  Initialy (first call to the recursion) the _list list should contain every segment of interest found on a mesh 
		*  AND the sement _s given in parameter should be the segment which has the maximum depth attribute (that means the less deeper in a natural langage).
		*  \ref explanationsabouttherecursivepart1 "See more explanations"
		*
		*  \param _list : List of segments that have been found on a mesh and not inserted yet in the final hierarchical tree.
		*  \param _s : Segment we want to create the node and the sons.
		*
		*  \return (void)
		*/
		void createFromMap_Eq_RecursivePart ( SegmentList _list, Segment* _s );
		
		/*!
		*  \brief Creates a hierarchical tree of segments by inclusion criteria.
		*
		*  Creates a hierarchical tree of segments by inclusion criteria : 
		*  The node which called the method will be one independant segment and its sons. And its brothers will be the other independants segments and their sons.
		*  The segments to put in the tree will be those which seed's value in the map respects the "EQUAL" criteria applied to the threshold given in parameter.
		*  \ref explanationsabouttree "See more explanations about these trees."
		*
		*  \param _thresh : Threshold to verify the criteria.
		*  \param _mesh : Mesh for which we want to compute the segments.
		*  \param _map : Map paired to the mesh containing the values for each vertex of the mesh to test the criteria.
		*
		*  \return (void)
		*/
		void createFromMap_Eq( double _thresh, Mesh _mesh, Map _map);
		
		/*!
		*  \brief Recursive method which creates a tree node from a segment picked into a list of all segment presents on the mesh.
		*
		*  Recursive method which creates a tree node from a segment picked into a list of all segment presents on the mesh :
		*  Creates the node from the segment AND the sons hierarchy of the node.
		*
		*  Initialy (first call to the recursion) the _list list should contain every segment of interest found on a mesh 
		*  AND the sement _s given in parameter should be the segment which has the maximum depth attribute (that means the less deeper in a natural langage).
		*  \ref explanationsabouttherecursivepart1 "See more explanations"
		*
		*
		*  \param _list : List of segments that have been found on a mesh and not inserted yet in the final hierarchical tree.
		*  \param _s : Segment we want to create the node and the sons.
		*
		*  \return (void)
		*/
		void createFromMap_LeEq_RecursivePart ( SegmentList& _list, Segment* _s );
		
		/*!
		*  \brief Creates a hierarchical tree of segments by inclusion criteria.
		*
		*  Creates a hierarchical tree of segments by inclusion criteria : 
		*  The node which called the method will be one independant segment and its sons. And its brothers will be the other independants segments and their sons.
		*  The segments to put in the tree will be those which seed's value in the map respects the "LESS OR EQUAL" criteria applied to the threshold given in parameter.
		*  \ref explanationsabouttree "See more explanations about these trees."
		*
		*  \param _thresh : Threshold to verify the criteria.
		*  \param _mesh : Mesh for which we want to compute the segments.
		*  \param _map : Map paired to the mesh containing the values for each vertex of the mesh to test the criteria.
		*
		*  \return (void)
		*/
		void createFromMap_LeEq( double _thresh, Mesh _mesh, Map _map);
		
		/*!
		*  \brief Recursive method which creates a tree node from a segment picked into a list of all segment presents on the mesh.
		*
		*  Recursive method which creates a tree node from a segment picked into a list of all segment presents on the mesh :
		*  Creates the node from the segment AND the sons hierarchy of the node.
		*
		*  Initialy (first call to the recursion) the _list list should contain every segment of interest found on a mesh 
		*  AND the sement _s given in parameter should be the segment which has the maximum depth attribute (that means the less deeper in a natural langage).
		*  \ref explanationsabouttherecursivepart1 "See more explanations"
		*
		*  \param _list : List of segments that have been found on a mesh and not inserted yet in the final hierarchical tree.
		*  \param _s : Segment we want to create the node and the sons.
		*
		*  \return (void)
		*/
		void createFromMap_GrEq_RecursivePart ( SegmentList& _list, Segment* _s );
		
		/*!
		*  \brief Creates a hierarchical tree of segments by inclusion criteria.
		*
		*  Creates a hierarchical tree of segments by inclusion criteria : 
		*  The node which called the method will be one independant segment and its sons. And its brothers will be the other independants segments and their sons.
		*  The segments to put in the tree will be those which seed's value in the map respects the "GREATER OR EQUAL" criteria applied to the threshold given in parameter.
		*  \ref explanationsabouttree "See more explanations about these trees."
		*
		*  \param _thresh : Threshold to verify the criteria.
		*  \param _mesh : Mesh for which we want to compute the segments.
		*  \param _map : Map paired to the mesh containing the values for each vertex of the mesh to test the criteria.
		*
		*  \return (void)
		*/
		void createFromMap_GrEq( double _thresh, Mesh _mesh, Map _map);
		
		/*!
		*  \brief Creates a Tree from the different segments according to a criteria on a mesh paired with a map.
		*
		*  Creates a Tree from the different segments according to a criteria on a mesh paired with a map given a mode and a threshold :
		*  The segments this method will find and add to the segment tree will be computed with the criteria parameter.
		*  Also, the different seeds for finding these segments will be all the vertices which values is verifying the criteria condition applied to the threshold.
		*  \ref explanationsabouttree "See more explanations about these trees."
		*  
		*
		*  \param _criteria : Criteria of segment creation. Can be set as EQUAL, GREATER_EQUAL or LESSER_EQUAL.
		*  \param _thresh : Threshold to be paired with the criteria to find the correct seeds for the segments creation.
		*  \param _mesh : Mesh paired with the _map map on which we want to create the tree.
		*  \param _map : Map paired with the _mesh mesh representing each vertices values.
		*
		*  \return (void)
		*/
		void createFromMap ( int _criteria, double _thresh, Mesh _mesh, Map _map );
		
		/*!
		*  \brief Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a given criteria.
		*
		*  Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a bounding box similarity along the Ox axe criteria.
		*
		*  \param _refBBox : Bounding box of the calling node's segment. MUST BE CONVERTED TO A PER CENTAGE OF THE MESH SUPPORTING THIS SEGMENT.
		*  \param _target : node containing the segment we want to compare.
		*  \param _targetMeshBBox : Bounding box of the mesh supporting the target node.
		*  \param _distMax : Distance maximum for a match to be validated.
		*
		*  \return (bool) Returns true if the criteria is verified, false else.
		*/
		bool matches_BBoxX ( BoundingBox _refBBox, SegmentTree *_target, BoundingBox _targetMeshBBox, int _distMax );
		
		/*!
		*  \brief Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a given criteria.
		*
		*  Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a bounding box similarity along the Oz axe criteria.
		*
		*  \param _refBBox : Bounding box of the calling node's segment. MUST BE CONVERTED TO A PER CENTAGE OF THE MESH SUPPORTING THIS SEGMENT.
		*  \param _target : node containing the segment we want to compare.
		*  \param _targetMeshBBox : Bounding box of the mesh supporting the target node.
		*  \param _distMax : Distance maximum for a match to be validated.
		*
		*  \return (bool) Returns true if the criteria is verified, false else.
		*/
		bool matches_BBoxY ( BoundingBox _refBBox, SegmentTree *_target, BoundingBox _targetMeshBBox, int _distMax );
		
		/*!
		*  \brief Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a given criteria.
		*
		*  Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a bounding box similarity along the Oz axe criteria.
		*
		*  \param _refBBox : Bounding box of the calling node's segment. MUST BE CONVERTED TO A PER CENTAGE OF THE MESH SUPPORTING THIS SEGMENT.
		*  \param _target : node containing the segment we want to compare.
		*  \param _targetMeshBBox : Bounding box of the mesh supporting the target node.
		*  \param _distMax : Distance maximum for a match to be validated.
		*
		*  \return (bool) Returns true if the criteria is verified, false else.
		*/
		bool matches_BBoxZ ( BoundingBox _refBBox, SegmentTree *_target, BoundingBox _targetMeshBBox, int _distMax );
		
		/*!
		*  \brief Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a given criteria.
		*
		*  Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a bot point similarity along the Ox axe criteria.
		*
		*  \param _refBBox : Bounding box of the calling node's segment. MUST BE CONVERTED TO A PER CENTAGE OF THE MESH SUPPORTING THIS SEGMENT.
		*  \param _target : node containing the segment we want to compare.
		*  \param _targetMeshBBox : Bounding box of the mesh supporting the target node.
		*  \param _distMax : Distance maximum for a match to be validated.
		*
		*  \return (bool) Returns true if the criteria is verified, false else.
		*/
		bool matches_BBoxBotX ( BoundingBox _refBBox, SegmentTree *_target, BoundingBox _targetMeshBBox, int _distMax );
		
		/*!
		*  \brief Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a given criteria.
		*
		*  Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a bot point similarity along the Oy axe criteria.
		*
		*  \param _refBBox : Bounding box of the calling node's segment. MUST BE CONVERTED TO A PER CENTAGE OF THE MESH SUPPORTING THIS SEGMENT.
		*  \param _target : node containing the segment we want to compare.
		*  \param _targetMeshBBox : Bounding box of the mesh supporting the target node.
		*  \param _distMax : Distance maximum for a match to be validated.
		*
		*  \return (bool) Returns true if the criteria is verified, false else.
		*/
		bool matches_BBoxBotY ( BoundingBox _refBBox, SegmentTree *_target, BoundingBox _targetMeshBBox, int _distMax );
		
		/*!
		*  \brief Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a given criteria.
		*
		*  Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a bot point similarity along the Oz axe criteria.
		*
		*  \param _refBBox : Bounding box of the calling node's segment. MUST BE CONVERTED TO A PER CENTAGE OF THE MESH SUPPORTING THIS SEGMENT.
		*  \param _target : node containing the segment we want to compare.
		*  \param _targetMeshBBox : Bounding box of the mesh supporting the target node.
		*  \param _distMax : Distance maximum for a match to be validated.
		*
		*  \return (bool) Returns true if the criteria is verified, false else.
		*/
		bool matches_BBoxBotZ ( BoundingBox _refBBox, SegmentTree *_target, BoundingBox _targetMeshBBox, int _distMax );
		
		/*!
		*  \brief Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a given criteria.
		*
		*  Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a top point similarity along the Ox axe criteria.
		*
		*  \param _refBBox : Bounding box of the calling node's segment. MUST BE CONVERTED TO A PER CENTAGE OF THE MESH SUPPORTING THIS SEGMENT.
		*  \param _target : node containing the segment we want to compare.
		*  \param _targetMeshBBox : Bounding box of the mesh supporting the target node.
		*  \param _distMax : Distance maximum for a match to be validated.
		*
		*  \return (bool) Returns true if the criteria is verified, false else.
		*/
		bool matches_BBoxTopX ( BoundingBox _refBBox, SegmentTree *_target, BoundingBox _targetMeshBBox, int _distMax );
		
		/*!
		*  \brief Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a given criteria.
		*
		*  Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a top point similarity along the Oy axe criteria.
		*
		*  \param _refBBox : Bounding box of the calling node's segment. MUST BE CONVERTED TO A PER CENTAGE OF THE MESH SUPPORTING THIS SEGMENT.
		*  \param _target : node containing the segment we want to compare.
		*  \param _targetMeshBBox : Bounding box of the mesh supporting the target node.
		*  \param _distMax : Distance maximum for a match to be validated.
		*
		*  \return (bool) Returns true if the criteria is verified, false else.
		*/
		bool matches_BBoxTopY ( BoundingBox _refBBox, SegmentTree *_target, BoundingBox _targetMeshBBox, int _distMax );
		
		/*!
		*  \brief Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a given criteria.
		*
		*  Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a top point similarity along the Oz axe criteria.
		*
		*  \param _refBBox : Bounding box of the calling node's segment. MUST BE CONVERTED TO A PER CENTAGE OF THE MESH SUPPORTING THIS SEGMENT.
		*  \param _target : node containing the segment we want to compare.
		*  \param _targetMeshBBox : Bounding box of the mesh supporting the target node.
		*  \param _distMax : Distance maximum for a match to be validated.
		*
		*  \return (bool) Returns true if the criteria is verified, false else.
		*/
		bool matches_BBoxTopZ ( BoundingBox _refBBox, SegmentTree *_target, BoundingBox _targetMeshBBox, int _distMax );
		
		/*!
		*  \brief Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a given criteria.
		*
		*  Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a depth similarity criteria.
		*
		*  \param _target : node containing the segment we want to compare.
		*  \param _distMax : Distance maximum for a match to be validated Set to 0 by default.
		*
		*  \return (bool) Returns true if the criteria is verified, false else.
		*/
		bool matches_Depth ( SegmentTree* _target, int _distMax = 0 );
		
		/*!
		*  \brief Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a given criteria.
		*
		*  Indicates wether or not a segment given in a node of a tree matches another segment given in another node in am area similarity criteria.
		*
		*  \param _areaRef : Area of the reference node's segment. MUST BE CONVERTED IN A PER CENTAGE OF THE REFERENCE MESH AREA.
		*  \param _target : Node containing the segment we want to compare.
		*  \param _targetMesh : Mesh supporting the target node's segment.
		*  \param _areaTargetMesh : Area of the target mesh.
		*  \param _distMax : Distance maximum for a match to be validated.
		*
		*  \return (bool) Returns true if the criteria is verified, false else.
		*/
		bool matches_Area ( double _areaRef, SegmentTree *_target, Mesh* _targetMesh, double _areaTargetMesh, double _distMax);
		
		/*!
		*  \brief Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a given criteria.
		*
		*  Indicates wether or not a segment given in a node of a tree matches another segment given in another node in an intersection criteria.
		*
		*  \param _target : Node containing the segment we want to compare.
		*
		*  \return (bool) Returns true if the criteria is verified, false else.
		*/
		bool matches_Intersection (SegmentTree *_target );
		
		/*!
		*  \brief Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a given criteria.
		*
		*  Indicates wether or not a segment given in a node of a tree matches another segment given in another node in a distance criteria.
		*
		*  \param _refMesh : Mesh supporting the calling node's segment.
		*  \param _target : Node containing the segment we want to compare.
		*  \param _distMax : Distance maximum for a match to be validated.
		*
		*  \return (bool) Returns true if the criteria is verified, false else.
		*/
		bool matches_Distance ( Mesh* _refMesh, SegmentTree* _target, int _distMax );
		
		/*!
		*  \brief Returns a possible score for the matching between the calling node and the target one.
		*
		*  Returns a possible score for the matching between the calling node and the target one.
		*  \warning THIS METHOD IS SUBJECTIVE (CHOICE OF WEIGHTS FOR EACH CRITERIA) AND CAN NOT BE CHANGED IN AN OTHER WAY THAN MODIFYING THE SOURCE CODE (NO PARAMETERS ARE GIVEN).
		*
		*  \param _refMesh : Mesh supporting the calling node's segment.
		*  \param _target : Node containing the segment we want to compare.
		*  \param _targetMesh : Mesh supporting the target node's segment.
		*
		*  \return (int) Returns thes score of the matching between the calling node and the target one.
		*/
		int getMatchScore ( Mesh* _refMesh, SegmentTree *_target, Mesh* _targetMesh );
		
		/*!
		*  \brief Does a morphological dilatation of a node's segment.
		*
		*  Does a morphological dilatation of a node's segment.
		*
		*  \param _mesh : Mesh supporting the nodes.
		*  \param _size : Size of the dilatation.
		*
		*  \return (void)
		*/
		void morphologicalDilatation ( Mesh _mesh, int _size );
		
		/*!
		*  \brief Overload of the morphologicalDilatation method.
		*/
		void morphologicalDilatation ( Mesh* _mesh, int _size );
		
		/*!
		*  \brief Does a morphological erosion of a node's segment.
		*
		*  Does a morphological erosion of a node's segment.
		*
		*  \param _mesh : Mesh supporting the nodes.
		*  \param _size : Size of the erosion.
		*
		*  \return (void)
		*/
		void morphologicalErosion ( Mesh _mesh, int _size );
		
		/*!
		*  \brief Overload of the morphologicalErosion method.
		*/
		void morphologicalErosion ( Mesh* _mesh, int _size );
		
		/*!
		*  \brief This method does a morphological opening (who would have gessed that ???) of all the segments in a tree.
		*
		*  This method does a morphological opening of all the segments in a tree :
		*  Because sometimes some sulcis are divided into two different parts separated by one or two edges, we would like to merge them to recreate one sulcus.
		*  Generally, the pointer set as the _tree parameter should be the one affected by the result :
		*
		*  \ref morphomathclosing "See more explanations."
		*
		*  \code 
		*		SegmentTree* tree = new SegmentTree();
		*		...
		*		tree = SegmentTree::filterArea ( mesh, tree, 1 );
		*  \endcode
		
		*  \param _mesh : Mesh supporting the sulcis.
		*  \param _thresh : Distance below which two sulcis are considered as having to be merged.
		*
		*  \return (void)
		*/
		void morphologicalClosing ( Mesh* _mesh, int _thresh );
		
		/*!
		*  \brief Displays the node's segment in a certain mode.
		*
		*  Displays the node's segment in a certain mode.
		*
		*  \param _mode : Mode to display the node. Can be OWN_COLOR, OTHER_COLOR or MESH_COLOR.
		*  \param _r : Red component of the color to display. ONLY IF THE MODE IS "OTHER_COLOR". Set to 1 by default.
		*  \param _g : Green component of the color to display. ONLY IF THE MODE IS "OTHER_COLOR". Set to 0 by default.
		*  \param _b : Blue component of the color to display. ONLY IF THE MODE IS "OTHER_COLOR". Set to 0 by default.
		*
		*  \return (void)
		*/
		void display( int _mode = MESH_COLOR, double _r = 1, double _g = 0, double _b = 0 );
		
		/*!
		*  \brief Displays the node's sons segments in a certain mode.
		*
		*  Displays the node's sons segments in a certain mode.
		*
		*  \param _mode : Mode to display the node. Can be OWN_COLOR, OTHER_COLOR or MESH_COLOR.
		*  \param _r : Red component of the color to display. ONLY IF THE MODE IS "OTHER_COLOR". Set to 1 by default.
		*  \param _g : Green component of the color to display. ONLY IF THE MODE IS "OTHER_COLOR". Set to 0 by default.
		*  \param _b : Blue component of the color to display. ONLY IF THE MODE IS "OTHER_COLOR". Set to 0 by default.
		*
		*  \return (void)
		*/
		void displaySons ( int _mode = MESH_COLOR, double _r = 1, double _g = 0, double _b = 0 );
		
		/*!
		*  \brief Displays the node's segment and its brothers' segments in a certain mode.
		*
		*  Displays the node's segment and its brothers' segments in a certain mode.
		*
		*  \param _mode : Mode to display the node. Can be OWN_COLOR, OTHER_COLOR, MESH_COLOR or PICKING. 
		*  The PICKING mode is kind of special. The RENDER mode of OpenGL should be activated before the call to this method.
		*  \param _r : Red component of the color to display. ONLY IF THE MODE IS "OTHER_COLOR". Set to 1 by default.
		*  \param _g : Green component of the color to display. ONLY IF THE MODE IS "OTHER_COLOR". Set to 0 by default.
		*  \param _b : Blue component of the color to display. ONLY IF THE MODE IS "OTHER_COLOR". Set to 0 by default.
		*
		*  \return (void)
		*/
		void displayBrotherhood ( int _mode = MESH_COLOR, double _r = 1, double _g = 0, double _b = 0 );
		
		/*!
		*  \brief Static function to remoev a node from a tree.
		*
		*  Static function to remoev a node from a tree.
		*
		*  \param _firstbrother : The first brother node of the node we want to remove.
		*  \param _toRemove : The node we want to remove from the tree.
		*
		*  \return (SegmentTree*) Returns the first brother of the tree (it may have changed if we suppressed it).
		*/
		static SegmentTree* removeNode ( SegmentTree* _firstBrother, SegmentTree* _toRemove );
		
		/*!
		*  \brief Filters a tree by a size (number of vertices) distance on the segment of each node.
		*
		*  Filters a tree by a size (number of vertices) distance on the segment of each node.
		*  Generally, the pointer set as the _tree parameter should be the one affected by the result :
		*
		*  \code 
		*		SegmentTree* tree = new SegmentTree();
		*		...
		*		tree = SegmentTree::filterSize ( tree, 10 );
		*  \endcode
		*
		*  \param _tree : Tree we want to filter.
		*  \param _thresh : Threshold to remove or not a node of the tree.
		*
		*  \return (SegmentTree*) Returns the first brother of the filtered tree (it may have changed).
		*/
		static SegmentTree* filterSize ( SegmentTree* _tree, int _thresh );

		/*!
		*  \brief Filters a tree by area on the segment of each node.
		*
		*  Filters a tree by area (per centage of the total area of the mesh) on the segment of each node.
		*  Generally, the pointer set as the _tree parameter should be the one affected by the result :
		*
		*  \code 
		*		SegmentTree* tree = new SegmentTree();
		*		...
		*		tree = SegmentTree::filterArea ( mesh, tree, 1 );
		*  \endcode
		*
		*  \param _mesh : Mesh supporting the tree to filter.
		*  \param _tree : Tree we want to filter.
		*  \param _thresh : Threshold to remove or not a node of the tree between 0 and 100 per cent.
		*
		*  \return (SegmentTree*) Returns the first brother of the filtered tree (it may have changed).
		*/
		static SegmentTree* filterArea ( Mesh* _mesh, SegmentTree *_tree, double _thresh);
		
		/*!
		*  \brief Splits the too big segments found automatically : they are replaced by their sons.
		*
		*  Splits the too big segments found automatically : they are replaced by their sons.
		*  Every segment of the tree given in parameter that have an area (in percentage of the mesh area) greater than the threshold are replaced by their sons.
		*  \ref explanationsaboutthesplittingtree "See more explanations."
		*
		*  \code 
		*		SegmentTree* tree = new SegmentTree();
		*		...
		*		tree = SegmentTree::splitTooBigSegments ( mesh, tree, 10 );
		*  \endcode
		*
		*  \param _mesh : Mesh supporting the tree to filter.
		*  \param _tree : Tree we want to filter.
		*  \param _thresh : Threshold to remove or not a node of the tree between 0 and 100 per cent.
		*
		*  \return (SegmentTree*) Returns the first brother of the new tree (it may have changed).
		*/
		static SegmentTree* splitTooBigSegments ( Mesh* _mesh, SegmentTree* _tree, double _thresh );

		/*!
		*  \brief This method does a morphological opening (who would have gessed that ???) of all the segments in a tree.
		*
		*  This method does a morphological opening of all the segments in a tree :
		*  Because sometimes some sulcis are divided into two different parts separated by one or two edges, we would like to merge them to recreate one sulcus.
		*  Generally, the pointer set as the _tree parameter should be the one affected by the result :
		*
		*  \ref morphomathclosing "See more explanations."
		*
		*  \code 
		*		SegmentTree* tree = new SegmentTree();
		*		...
		*		tree = SegmentTree::filterArea ( mesh, tree, 1 );
		*  \endcode
		
		*  \param _mesh : Mesh supporting the sulcis.
		*  \param _thresh : Distance below which two sulcis are considered as having to be merged.
		*
		*  \return (void)
		*/
		static SegmentTree* morphologicalClosing ( SegmentTree* _tree, Mesh* _mesh, int _thresh );
		
//		static SegmentTree* morphologicalClosingFake(SegmentTree *_tree, Mesh *_mesh, int _thresh);
		
		static SegmentTree* groupSegments ( SegmentTree* _tree, Mesh _mesh, int _distMax );
		
		/*!
		*  \brief Prints some informations about the node in the terminal.
		*
		*  Prints some informations about the node in the terminal.
		*
		*  \param _mesh : Mesh supporting the tree to print. Usefull for calculating the area of the segment for example. By default NULL, so that any information requiring the mesh will be printed.
		*
		*  \return (SegmentTree*) Returns the first brother of the new tree (it may have changed).
		*/
		void print( Mesh* _mesh = NULL );
		
		
};

#endif
